
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

typedef struct
{
    int res;
    int count;
    pthread_cond_t cond;
    pthread_mutex_t mutex;
} Result;

void *set_fn(void *arg)
{

    int i = 1, sum = 0;
    for (; i < 1000; ++i)
    {
        sum += i;
    }

    Result *result = (Result *)arg;

    pthread_mutex_lock(&result->mutex);
    while (result->count < 2)
    {
        pthread_mutex_unlock(&result->mutex);
        sleep(1);
        pthread_mutex_lock(&result->mutex);
    }
    result->res = sum;
    pthread_mutex_unlock(&result->mutex);

    pthread_cond_broadcast(&result->cond);
    return (void *)0;
}

void *get_fn(void *arg)
{
    Result *result = (Result *)arg;

    pthread_mutex_lock(&result->mutex);
    result->count++;

    pthread_cond_wait(&result->cond, &result->mutex);

    printf("%lx get res = %d\n", pthread_self(), result->res);

    pthread_mutex_unlock(&result->mutex);

    return (void *)0;
}

int main()
{

    pthread_t set, get1, get2;

    Result result;
    result.count = 0;
    pthread_cond_init(&result.cond, NULL);
    pthread_mutex_init(&result.mutex, NULL);

    if (pthread_create(&set, NULL, set_fn, &result) != 0)
    {
        fprintf(stderr, "set pthread_create error!\n");
        exit(EXIT_FAILURE);
    }

    if (pthread_create(&get1, NULL, get_fn, &result) != 0)
    {
        fprintf(stderr, "get1 pthread_create error!\n");
        exit(EXIT_FAILURE);
    }

    if (pthread_create(&get2, NULL, get_fn, &result) != 0)
    {
        fprintf(stderr, "get2 pthread_create error!\n");
        exit(EXIT_FAILURE);
    }

    pthread_join(set, NULL);
    pthread_join(get1, NULL);
    pthread_join(get2, NULL);

    return 0;
}